rm(list=ls())

library(tidyverse); library(gridExtra); library(ggprism); library(stargazer); library(psych); library(xtable); library(marginaleffects); library(ggplot2)

# load and inspect data
manifestos <- read.csv("manifestos.csv")
head(manifestos)

###
### Figure 3.1: Keyword Ratio in Speeches and Manifestos
### (b) State and federal level manifestos (1975-2024)
###
mani_crime_plot <- aggregate(cbind(log_ratio, bias_imp) ~ year + partyname, data=manifestos, FUN=mean, na.rm=TRUE, na.action=NULL)
mani_crime_plot <- mani_crime_plot %>% 
  pivot_longer( cols=c(log_ratio, bias_imp))
head(mani_crime_plot)
mani_crime_plot$partyname <- ifelse(mani_crime_plot$partyname=="CDU/CSU", "CDU", mani_crime_plot$partyname)
mani_crime_plot <- subset(mani_crime_plot, partyname!="AFD")
mani_crime_plot$partyname <- factor(mani_crime_plot$partyname, ordered=T, levels=c("CDU", "SPD", "FDP", "Greens", "Left"))
position <- subset(mani_crime_plot , name=="log_ratio")

a.plot <- 
  ggplot(position, aes(year, value)) + theme_bw() + 
  facet_wrap(~partyname, ncol=5) +  geom_line() +
  ylab("Position") + geom_hline(yintercept=0, linetype="dashed") +
  scale_x_continuous(guide = "prism_minor", 
                     expand = c(0, 0)
  ) +
  theme(axis.text.x=element_blank(), axis.title.x=element_blank(), 
        axis.text.y = element_text(size=12), axis.title.y = element_text(size=16),
        prism.ticks.length.x = unit(5, "pt"),#adjust length of minor tick marks
        legend.position="none",#suppress legend,
        strip.text.x = element_text(size=14), #change color and size of facet strip text
        panel.spacing = unit(1, "lines"), #add more space between panels to better fit axis tick labels
        plot.margin = unit(c(.5, .5, .1, .1), "cm"),#adjust spacing between panels
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank()
  )

bias <- subset(mani_crime_plot, name=="bias_imp")

b.plot <- 
  ggplot(bias, aes(year, value)) + theme_bw() + 
  facet_wrap(~partyname, ncol=5) +  geom_line() +
  ylab("Bias") + geom_hline(yintercept=0, linetype="dashed") +
  scale_x_continuous(guide = "prism_minor", 
                     expand = c(0, 0)
  ) +
  theme(axis.text.x = element_text(size=12), axis.title.x=element_blank(), 
        axis.text.y = element_text(size=12), axis.title.y = element_text(size=16),
        prism.ticks.length.x = unit(5, "pt"),#adjust length of minor tick marks
        legend.position="none",#suppress legend,
        strip.text.x = element_text(size=14), #change color and size of facet strip text
        panel.spacing = unit(1, "lines"), #add more space between panels to better fit axis tick labels
        plot.margin = unit(c(.5, .5, .1, .1), "cm"),#adjust spacing between panels
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank()
  )

# combined into single PDF
pdf("Fig3_1b.pdf", height=7, width=12)
grid.arrange(a.plot , b.plot, nrow=2)
dev.off()


###
### Table B.4: Regression of Keywords in Manifestos on Parties
###
manifestos$partyname <- ifelse(manifestos$partyname=="CDU/CSU", "CDU", manifestos$partyname)
manifestos$partyname <- ifelse(manifestos$partyname=="AFD", "AfD", manifestos$partyname)
manifestos$partyname <- factor(manifestos$partyname, levels = c("AfD", "CDU", "FDP", "Greens", "Left", "SPD"))
manifestos$partyname <- relevel(manifestos$partyname, ref = "CDU") # make CDU/CSU reference party
manifestos$decade <- (manifestos$year %/% 10)*10 # create decade variable
mod1 <- lm(log_ratio ~ as.factor(partyname), manifestos)
mod2 <- lm(log_ratio ~ as.factor(partyname) + as.factor(statename), manifestos)
mod3 <- lm(log_ratio ~ as.factor(partyname) + as.factor(statename) + as.factor(decade), manifestos)
mod4 <- lm(log_ratio ~ as.factor(partyname) + as.factor(statename) + as.factor(year), manifestos)
mod5 <- lm(bias_imp ~ as.factor(partyname), manifestos)
mod6 <- lm(bias_imp ~ as.factor(partyname) + as.factor(statename), manifestos)
mod7 <- lm(bias_imp ~ as.factor(partyname) + as.factor(statename) + as.factor(decade), manifestos)
mod8 <- lm(bias_imp ~ as.factor(partyname) + as.factor(statename) + as.factor(year), manifestos)
stargazer(mod1, mod2, mod3, mod4, mod5, mod6, mod7, mod8,
          digits=2, star.cutoffs = c(0.05, 0.01, NA), dep.var.labels.include = FALSE, no.space=T,
          dep.var.caption="Outcome variable: logged ratio",
          omit.stat = c("f", "rsq", "ser"),
          add.lines = list(c("State FEs", "", "checkmark", "checkmark", "checkmark", "", "checkmark", "checkmark", "checkmark"),
                           c("Year FEs", "", "", "", "checkmark", "", "", "", "checkmark"),
                           c("Decade FEs", "", "", "checkmark", "", "", "", "checkmark", "")))


###
### Figure 3.3: Regression of Keywords in Manifestos on Parties
###
ests_poll = rbind.data.frame(summary(mod1)$coefficients[2:6,1:2], summary(mod4)$coefficients[2:6,1:2],
                             summary(mod5)$coefficients[2:6,1:2], summary(mod8)$coefficients[2:6,1:2])
names(ests_poll) = c("coef", "se")
ests_poll$party = rep(c("AfD", "FDP", "Greens", "Left", "SPD"), 4)
ests_poll$model = rep(c("w/o Fixed Effects", "w/ Year and State Fixed Effects"), each=5)
ests_poll$model <- factor(ests_poll$model, levels=c("w/o Fixed Effects", "w/ Year and State Fixed Effects"))
ests_poll$outcome <- rep(c("Position", "Bias"), each=10)
ests_poll$outcome <- factor(ests_poll$outcome, levels=c("Position", "Bias"))

pdf("Fig3_3.pdf", width = 9, height=5)
ggplot(data=ests_poll, aes(x=party, y=coef, group=factor(party), shape=factor(model))) + 
  geom_point(position=position_dodge2(0.5), size=2.5) + 
  geom_errorbar(aes(ymax=coef+1.96*se, ymin=coef-1.96*se), width=0, position=position_dodge(0.5), group=factor("party")) +
  theme_bw() + facet_wrap(~outcome) +
  geom_hline(yintercept = 0, linetype="dashed") +
  theme(legend.position = "bottom", text = element_text(size=18), panel.grid = element_blank()) +
  xlab("") + 
  ylab("Difference to CDU/CSU") +
  scale_shape_manual(values=c(16, 17), name="")
dev.off()


###
### Figure B.1: Keyword Ratio in Speeches and Manifestos
### (b) State and federal level manifestos (1975-2024)
###
twolines <- subset(manifestos, partyname!="AfD")
twolines$centerleft <- ifelse((twolines$partyname=="CDU" | twolines$partyname=="FDP"), 0, 1)
table(twolines$centerleft, twolines$partyname, useNA="ifany")
twolines <- aggregate(log_ratio ~ year + centerleft, data=twolines, FUN=mean)
pdf("FigB1b.pdf", height=8,width=14)
ggplot(data=twolines, aes(x=year, y=log_ratio, color=as.factor(centerleft))) +
  geom_point(aes(shape = as.factor(centerleft))) + geom_line() +
  scale_color_manual(values=c("dodgerblue", "firebrick"), 
                     labels=c("Center-Right", "Center-Left"), name="") +
  scale_shape_manual(values=c(17, 16), 
                     labels=c("Center-Right", "Center-Left"), name="") +
  ylab("Logged ratio") + xlab("Year") +
  theme_classic(base_size = 22) +
  geom_hline(yintercept = 0, linetype="dashed", color="grey") +
  theme(panel.grid.minor = element_blank(), legend.position = "bottom") +
  guides(linetype=F)
dev.off()


###
### Table B.2: Manifestos: Descriptive Statistics
###
xtable(describe(manifestos[,c("count_right", "count_left", "log_ratio", "extreme_crime_ratio_log_imp", "bias_imp")])[,c(2,3,4,8,9)])
xtable(describe(manifestos[manifestos$partyname=="CDU",c("count_right", "count_left", "log_ratio", "extreme_crime_ratio_log_imp", "bias_imp")])[,c(2,3,4,8,9)])
xtable(describe(manifestos[manifestos$partyname=="SPD",c("count_right", "count_left", "log_ratio", "extreme_crime_ratio_log_imp", "bias_imp")])[,c(2,3,4,8,9)])
xtable(describe(manifestos[manifestos$partyname=="FDP",c("count_right", "count_left", "log_ratio", "extreme_crime_ratio_log_imp", "bias_imp")])[,c(2,3,4,8,9)])
xtable(describe(manifestos[manifestos$partyname=="Greens",c("count_right", "count_left", "log_ratio", "extreme_crime_ratio_log_imp", "bias_imp")])[,c(2,3,4,8,9)])
xtable(describe(manifestos[manifestos$partyname=="Left",c("count_right", "count_left", "log_ratio", "extreme_crime_ratio_log_imp", "bias_imp")])[,c(2,3,4,8,9)])
xtable(describe(manifestos[manifestos$partyname=="AfD",c("count_right", "count_left", "log_ratio", "extreme_crime_ratio_log_imp", "bias_imp")])[,c(2,3,4,8,9)])


###
### Table B.6: Regression of Keywords in Manifestos on Parties, No Logged Ratio
###
mod1 <- lm(diff ~ as.factor(partyname), manifestos)
mod2 <- lm(diff ~ as.factor(partyname) + as.factor(statename), manifestos)
mod3 <- lm(diff ~ as.factor(partyname) + as.factor(statename) + as.factor(decade), manifestos)
mod4 <- lm(diff ~ as.factor(partyname) + as.factor(statename) + as.factor(year), manifestos)
mod5 <- lm(bias_imp_diff ~ as.factor(partyname), manifestos)
mod6 <- lm(bias_imp_diff ~ as.factor(partyname) + as.factor(statename), manifestos)
mod7 <- lm(bias_imp_diff ~ as.factor(partyname) + as.factor(statename) + as.factor(decade), manifestos)
mod8 <- lm(bias_imp_diff ~ as.factor(partyname) + as.factor(statename) + as.factor(year), manifestos)
stargazer(mod1, mod2, mod3, mod4, mod5, mod6, mod7, mod8,
          digits=2, star.cutoffs = c(0.05, 0.01, NA), dep.var.labels.include = FALSE, no.space=T,
          dep.var.caption="Outcome variable: logged ratio",
          omit.stat = c("f", "rsq", "ser"),
          add.lines = list(c("State FEs", "", "checkmark", "checkmark", "checkmark", "", "checkmark", "checkmark", "checkmark"),
                           c("Year FEs", "", "", "", "checkmark", "", "", "", "checkmark"),
                           c("Decade FEs", "", "", "checkmark", "", "", "", "checkmark", "")))


###
### Table B.8: Regression of Keywords in Manifestos on Parties and Far-Right Polling
###
mod1 <- lm(log_ratio ~ as.factor(partyname)*polbar_fr_vote_pct, manifestos)
mod2 <- lm(log_ratio ~ as.factor(partyname)*polbar_fr_vote_pct + as.factor(statename), manifestos)
mod3 <- lm(log_ratio ~ as.factor(partyname)*polbar_fr_vote_pct + as.factor(statename) + as.factor(decade), manifestos)
mod4 <- lm(log_ratio ~ as.factor(partyname)*polbar_fr_vote_pct + as.factor(statename) + as.factor(year), manifestos)
mod5 <- lm(bias_imp ~ as.factor(partyname)*polbar_fr_vote_pct, manifestos)
mod6 <- lm(bias_imp ~ as.factor(partyname)*polbar_fr_vote_pct + as.factor(statename), manifestos)
mod7 <- lm(bias_imp ~ as.factor(partyname)*polbar_fr_vote_pct + as.factor(statename) + as.factor(decade), manifestos)
mod8 <- lm(bias_imp ~ as.factor(partyname)*polbar_fr_vote_pct + as.factor(statename) + as.factor(year), manifestos)
stargazer(mod1, mod2, mod3, mod4, mod5, mod6, mod7, mod8,
          digits=2, star.cutoffs = c(0.05, 0.01, NA), dep.var.labels.include = FALSE, no.space=T,
          dep.var.caption="Outcome variable: logged ratio",
          omit.stat = c("f", "rsq", "ser"),
          add.lines = list(c("State FEs", "", "checkmark", "checkmark", "checkmark", "", "checkmark", "checkmark", "checkmark"),
                           c("Year FEs", "", "", "", "checkmark", "", "", "", "checkmark"),
                           c("Decade FEs", "", "", "checkmark", "", "", "", "checkmark", "")))


###
### Extract coefficients and SEs for 
### Figure 3.7: Effect of Far-Right Polling on Speeches, Manifestos, and Inquiries
### (see separate script)
###
ests_poll =  rbind.data.frame(avg_slopes(mod4, variables="polbar_fr_vote_pct", by="partyname")[,3:5],
                              avg_slopes(mod8, variables="polbar_fr_vote_pct", by="partyname")[,3:5])
ests_poll = as.data.frame(ests_poll)
names(ests_poll) = c("party", "coef", "se")


###
### Table B.10: Regression of Keywords in Manifestos on Parties – Restricted Set of Keywords
###
mod1 <- lm(log_ratio_restricted ~ as.factor(partyname), manifestos)
mod2 <- lm(log_ratio_restricted ~ as.factor(partyname) + as.factor(statename), manifestos)
mod3 <- lm(log_ratio_restricted ~ as.factor(partyname) + as.factor(statename) + as.factor(decade), manifestos)
mod4 <- lm(log_ratio_restricted ~ as.factor(partyname) + as.factor(statename) + as.factor(year), manifestos)
mod5 <- lm(bias_imp_restr ~ as.factor(partyname), manifestos)
mod6 <- lm(bias_imp_restr ~ as.factor(partyname) + as.factor(statename), manifestos)
mod7 <- lm(bias_imp_restr ~ as.factor(partyname) + as.factor(statename) + as.factor(decade), manifestos)
mod8 <- lm(bias_imp_restr ~ as.factor(partyname) + as.factor(statename) + as.factor(year), manifestos)
stargazer(mod1, mod2, mod3, mod4, mod5, mod6, mod7, mod8,
          digits=2, star.cutoffs = c(0.05, 0.01, NA), dep.var.labels.include = FALSE, no.space=T,
          dep.var.caption="Outcome variable: logged ratio",
          omit.stat = c("f", "rsq", "ser"),
          add.lines = list(c("State FEs", "", "checkmark", "checkmark", "checkmark", "", "checkmark", "checkmark", "checkmark"),
                           c("Year FEs", "", "", "", "checkmark", "", "", "", "checkmark"),
                           c("Decade FEs", "", "", "checkmark", "", "", "", "checkmark", "")))


###
### Table B.12: Regression of Keywords in Manifestos on Parties – Violent Crimes Only
###
mod1 <- lm(bias_imp_violent ~ as.factor(partyname), manifestos)
mod2 <- lm(bias_imp_violent ~ as.factor(partyname) + as.factor(statename), manifestos)
mod3 <- lm(bias_imp_violent ~ as.factor(partyname) + as.factor(statename) + as.factor(decade), manifestos)
mod4 <- lm(bias_imp_violent ~ as.factor(partyname) + as.factor(statename) + as.factor(year), manifestos)
stargazer(mod1, mod2, mod3, mod4, 
          digits=2, star.cutoffs = c(0.05, 0.01, NA), dep.var.labels.include = FALSE, no.space=T,
          dep.var.caption="Outcome variable: bias",
          omit.stat = c("f", "rsq", "ser"),
          add.lines = list(c("State FEs", "", "checkmark", "checkmark", "checkmark", "", "checkmark", "checkmark", "checkmark"),
                           c("Year FEs", "", "", "", "checkmark", "", "", "", "checkmark"),
                           c("Decade FEs", "", "", "checkmark", "", "", "", "checkmark", "")))


###
### Table B.14: Regression of Keywords in Manifestos on Parties – Violent Crimes since 2000
###
since2000 <- subset(manifestos, year>1999)
mod1 <- lm(bias_imp_violent ~ as.factor(partyname), since2000)
mod2 <- lm(bias_imp_violent ~ as.factor(partyname) + as.factor(statename), since2000)
mod3 <- lm(bias_imp_violent ~ as.factor(partyname) + as.factor(statename) + as.factor(decade), since2000)
mod4 <- lm(bias_imp_violent ~ as.factor(partyname) + as.factor(statename) + as.factor(year), since2000)
stargazer(mod1, mod2, mod3, mod4, 
          digits=2, star.cutoffs = c(0.05, 0.01, NA), dep.var.labels.include = FALSE, no.space=T,
          dep.var.caption="Outcome variable: bias",
          omit.stat = c("f", "rsq", "ser"),
          add.lines = list(c("State FEs", "", "checkmark", "checkmark", "checkmark", "", "checkmark", "checkmark", "checkmark"),
                           c("Year FEs", "", "", "", "checkmark", "", "", "", "checkmark"),
                           c("Decade FEs", "", "", "checkmark", "", "", "", "checkmark", "")))
